frappe.provide("frappe.treeview_settings")

frappe.treeview_settings["Account"] = {
    breadcrumb: "Accounts",
    title: __("Chart of Accounts"),
    get_tree_root: false,
    filters: [
        {
            fieldname: "company",
            fieldtype: "Select",
            options: erpnext.utils.get_tree_options("company"),
            label: __("Company"),
            default: erpnext.utils.get_tree_default("company"),
            on_change: function () {
                var me = frappe.treeview_settings["Account"].treeview
                var company = me.page.fields_dict.company.get_value()
                if (!company) {
                    frappe.throw(__("Please set a Company"))
                }
                frappe.call({
                    method: "erpnext.accounts.doctype.account.account.get_root_company",
                    args: {
                        company: company,
                    },
                    callback: function (r) {
                        if (r.message) {
                            let root_company = r.message.length ? r.message[0] : ""
                            me.page.fields_dict.root_company.set_value(root_company)

                            frappe.db.get_value(
                                "Company",
                                { name: company },
                                "allow_account_creation_against_child_company",
                                r => {
                                    frappe.flags.ignore_root_company_validation =
                                        r.allow_account_creation_against_child_company
                                }
                            )
                        }
                    },
                })
            },
        },
        {
            fieldname: "root_company",
            fieldtype: "Data",
            label: __("Root Company"),
            hidden: true,
            disable_onchange: true,
        },
    ],
    root_label: "Accounts",
    get_tree_nodes: "erpnext.accounts.utils.get_children",
    on_get_node: function (nodes, deep = false) {
        if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return

        let accounts = []
        if (deep) {
            // in case of `get_all_nodes`
            accounts = nodes.reduce((acc, node) => [...acc, ...node.data], [])
        } else {
            accounts = nodes
        }

        frappe.db.get_single_value("Accounts Settings", "show_balance_in_coa").then(value => {
            if (value) {
                const get_balances = frappe.call({
                    method: "erpnext.accounts.utils.get_account_balances",
                    args: {
                        accounts: accounts,
                        company: cur_tree.args.company,
                    },
                })

                get_balances.then(r => {
                    if (!r.message || r.message.length == 0) return

                    for (let account of r.message) {
                        const node = cur_tree.nodes && cur_tree.nodes[account.value]
                        if (!node || node.is_root) continue

                        // show Dr if positive since balance is calculated as debit - credit else show Cr
                        const balance = account.balance_in_account_currency || account.balance
                        // const dr_or_cr = balance > 0 ? "Dr" : "Cr"
                        const dr_or_cr = balance > 0 ? "借" : "贷"
                        const format = (value, currency) => format_currency(Math.abs(value), currency)
                        const color = dr_or_cr === "借" ? "blue" : "red"

                        if (account.balance !== undefined) {
                            node.parent && node.parent.find(".balance-area").remove()
                            $(
                                `<span class="balance-area pull-right" style="color: ${color} !important;">` +
                                    (account.balance_in_account_currency
                                        ? format(account.balance_in_account_currency, account.account_currency) +
                                          " / "
                                        : "") +
                                    format(account.balance, account.company_currency) +
                                    " " +
                                    dr_or_cr +
                                    "</span>"
                            ).insertBefore(node.$ul)
                        }
                    }
                })
            }
        })
    },
    add_tree_node: "erpnext.accounts.utils.add_ac",
    menu_items: [
        {
            label: __("New Company"),
            action: function () {
                frappe.new_doc("Company", true)
            },
            condition: 'frappe.boot.user.can_create.indexOf("Company") !== -1',
        },
    ],
    fields: [
        {
            fieldtype: "Data",
            fieldname: "account_name",
            label: __("New Account Name"),
            reqd: true,
            description: __("Name of new Account. Note: Please don't create accounts for Customers and Suppliers"),
        },
        {
            fieldtype: "Data",
            fieldname: "account_number",
            label: __("Account Number"),
            description: __("Number of new Account, it will be included in the account name as a prefix"),
        },
        {
            fieldtype: "Check",
            fieldname: "is_group",
            label: __("Is Group"),
            description: __(
                "Further accounts can be made under Groups, but entries can be made against non-Groups"
            ),
        },
        {
            fieldtype: "Select",
            fieldname: "root_type",
            label: __("Root Type"),
            options: ["Asset", "Liability", "Equity", "Income", "Expense"].join("\n"),
            depends_on: "eval:doc.is_group && !doc.parent_account",
        },
        {
            fieldtype: "Select",
            fieldname: "account_type",
            label: __("Account Type"),
            options: frappe.get_meta("Account").fields.filter(d => d.fieldname == "account_type")[0].options,
            description: __("Optional. This setting will be used to filter in various transactions."),
        },
        {
            fieldtype: "Float",
            fieldname: "tax_rate",
            label: __("Tax Rate"),
            depends_on: 'eval:doc.is_group==0&&doc.account_type=="Tax"',
        },
        {
            fieldtype: "Link",
            fieldname: "account_currency",
            label: __("Currency"),
            options: "Currency",
            description: __("Optional. Sets company's default currency, if not specified."),
        },
    ],
    ignore_fields: ["parent_account"],
    onload: function (treeview) {
        frappe.treeview_settings["Account"].treeview = {}
        $.extend(frappe.treeview_settings["Account"].treeview, treeview)
        function get_company() {
            return treeview.page.fields_dict.company.get_value()
        }

        // tools
        treeview.page.add_inner_button(
            __("Chart of Cost Centers"),
            function () {
                frappe.set_route("Tree", "Cost Center", { company: get_company() })
            },
            __("View")
        )

        treeview.page.add_inner_button(
            __("Opening Invoice Creation Tool"),
            function () {
                frappe.set_route("Form", "Opening Invoice Creation Tool", { company: get_company() })
            },
            __("View")
        )

        treeview.page.add_inner_button(
            __("Period Closing Voucher"),
            function () {
                frappe.set_route("List", "Period Closing Voucher", { company: get_company() })
            },
            __("View")
        )

        treeview.page.add_inner_button(
            __("Journal Entry"),
            function () {
                frappe.new_doc("Journal Entry", { company: get_company() })
            },
            __("Create")
        )
        treeview.page.add_inner_button(
            __("Company"),
            function () {
                frappe.new_doc("Company")
            },
            __("Create")
        )

        // financial statements
        for (let report of [
            "Trial Balance",
            "General Ledger",
            "Balance Sheet",
            "Profit and Loss Statement",
            "Cash Flow",
            "Accounts Payable",
            "Accounts Receivable",
        ]) {
            treeview.page.add_inner_button(
                __(report),
                function () {
                    frappe.set_route("query-report", report, { company: get_company() })
                },
                __("Financial Statements")
            )
        }
    },
    post_render: function (treeview) {
        frappe.treeview_settings["Account"].treeview["tree"] = treeview.tree
        if (treeview.can_create) {
            treeview.page.set_primary_action(
                __("New"),
                function () {
                    let root_company = treeview.page.fields_dict.root_company.get_value()
                    if (root_company) {
                        frappe.throw(__("Please add the account to root level Company - {0}"), [root_company])
                    } else {
                        treeview.new_node()
                    }
                },
                "add"
            )
        }
    },
    toolbar: [
        {
            label: __("Add Child"),
            condition: function (node) {
                return (
                    frappe.boot.user.can_create.indexOf("Account") !== -1 &&
                    (!frappe.treeview_settings["Account"].treeview.page.fields_dict.root_company.get_value() ||
                        frappe.flags.ignore_root_company_validation) &&
                    node.expandable &&
                    !node.hide_add
                )
            },
            click: function () {
                var me = frappe.views.trees["Account"]
                me.new_node()
            },
            btnClass: "hidden-xs",
        },
        {
            condition: function (node) {
                return !node.root && frappe.boot.user.can_read.indexOf("GL Entry") !== -1
            },
            label: __("View Ledger"),
            click: function (node, btn) {
                frappe.route_options = {
                    account: node.label,
                    from_date: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
                    to_date: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
                    company: frappe.treeview_settings["Account"].treeview.page.fields_dict.company.get_value(),
                }
                frappe.set_route("query-report", "General Ledger")
            },
            btnClass: "hidden-xs",
        },
    ],
    extend_toolbar: true,
}
